<?php

namespace StudyBuddy;

/**
 * Class responsible for adding/updating
 * a per-user tags counter collection
 *
 * This collection will be used for displaying
 * per - user tag stats on user profile page
 * can also be used for data mining but for that
 * a separate script has to run periodically like
 * once a day and maintain $tag => users array
 */
class UserTags extends StudyBuddyObject {
    const USER_TAGS = 'USER_TAGS';

    public function __construct(Registry $oRegistry) {
        $this->oRegistry = $oRegistry;
    }

    /**
     * Add array of tags to per-user tags collection
     *
     * @param int $uid
     * @param Question $oQuestion
     */
    public function addTags($uid, \StudyBuddy\Question $oQuestion) {
        /**
         * Questions that come from external APIs may not
         * have any user associated with it, uid is 0 or null then
         * in this case we should not attempt to
         * insert user tags, just return
         */
        if (empty($uid)) {

            return;
        }

        $uid = (int) $uid;

        $aTags = $oQuestion['a_tags'];

        /**
         * Extra precaution to filter out
         * empty values
         */
        $aTags = \array_filter($aTags);


        $coll = $this->oRegistry->Mongo->getCollection(self::USER_TAGS);
        $a = $coll->findOne(array('_id' => $uid));

        /**
         * If there is not record of tags for this user yet,
         * then we will make array with $tag => 1
         * and will use that,
         *
         * otherwise loop over existing array of tags,
         * increasing count, then sorting in descending
         * order by count and same to collection
         */
        if (empty($a)) {
            $aTemp = array_count_values($aTags);
        } else {
            $aTemp = $a['tags'];
            foreach ($aTags as $t) {
                /**
                 * Under no cercumstances should we allow
                 * an empty value to make its way into this array
                 * since this array is indexed and empty values
                 * in index may cause very bad times in Mongo.
                 */
                if (empty($t)) {
                    //e('Strangly enough there is an empty value of the tag in array: '.print_r($aTags, 1));

                    continue;
                }

                if (array_key_exists($t, $aTemp)) {
                    $aTemp[$t] += 1;
                } else {
                    $aTemp[$t] = 1;
                }
            }

            arsort($aTemp, SORT_NUMERIC);
        }

        $coll->save(array('_id' => $uid, 'tags' => $aTemp, 'i_count' => count($aTemp)), array('fsync' => true));

        return $this;
    }

    /**
     *
     * When question is marked deleted OR is retaged
     * we must update the user tags to account
     * for all tags in the removed question
     *
     * @param Question $oQuestion
     */
    public function removeTags(Question $oQuestion, $uid = null) {

        /**
         * If question is deleted
         * then dont update anything
         *
         */
        $uid = ($uid) ? (int) $uid : $oQuestion->getOwnerId();


        $aTags = $oQuestion['a_tags'];


        /**
         * Extra precaution to filter out
         * empty values
         */
        $aTags = array_filter($aTags);

        $coll = $this->oRegistry->Mongo->getCollection(self::USER_TAGS);
        $a = $coll->findOne(array('_id' => $uid));

        if (empty($a) || empty($a['tags'])) {


            return $this;
        }

        $aUserTags = $a['tags'];

        foreach ($aTags as $t) {
            if (array_key_exists($t, $aUserTags)) {
                $aUserTags[$t] -= 1;
                if ($aUserTags[$t] < 1) {
                    $aUserTags[$t] = false;
                }
            }
        }

        /**
         * Remove empty values
         * in case a count of tags has reached 0
         * in the process.
         * Otherwise bad times will happend as an empty value
         * will make its way into Mongo Index since this
         * array is indexed. Mongo does not allow empty values
         * in index and will throw exception or error
         *
         */
        $aUserTags = \array_filter($aUserTags);

        arsort($aUserTags, SORT_NUMERIC);

        $coll->save(array('_id' => $uid, 'tags' => $aUserTags, 'i_count' => count($aUserTags)), array('fsync' => true));

        return $this;
    }

}
